/**************************************************************************/ /**
 * @file     ui_page.h
 * @brief    UI 页面布局
 * @version  V2.0
 * @date     2022.03.15
 ******************************************************************************/
#ifndef __UI_PAGE_H__
#define __UI_PAGE_H__

#include "image_source.h"
#include "load_file.h"
#include "load_mv.h"
#include "log.h"

#include "ui_event.h"
#include "ui_bootloader.h"

//------------------------------------------图标对齐计算宏------------------------------------------//
//仅为了适应本例程不同分辨率的素材: 使得 ICON 均等散布于屏幕, 视觉对齐, 每个 ICON 的间距 <=> ICON 与屏幕边缘的间距 都是相等的
//实际应用时: 在 UI 设计阶段即可确定界面风格与坐标, 且 lvgl 提供容器的多种布局对齐, 使用相对位置偏移更利于后期修改
//故而在实际应用无须使用以下宏

// X 轴 : LV_HOR_RES_MAX

/* 在[0, x]区间 : 对齐 n 个宽为 w 的 ICON 
 * => 均等取得每个 ICON 相对偏移 - x轴
 * [0 <- (offset) -> icon_w <- (offset) -> icon_w ..... -> x]
 */
#define	GET_OFFSET_X(x, w, n)				( ( (x) - ( (w) * (n) ) ) / ( (n) + 1 ) )

/* 在[s, s + x]区间 : 按 offset 偏移对齐宽为 w 的 ICON 
 * => 得出对齐第 i 个 ICON 的绝对位置 - x轴
 */
#define	GET_X(i, s, w, offset)				( ( ( (w) * (i) ) + ( (offset) * ( (i) + 1 ) ) ) + (s) )


// Y 轴 : LV_VER_RES_MAX

/* 在[0, y]区间 : 对齐 n 个高为 h 的 ICON 
 * => 均等取得每个 ICON 相对偏移 - y轴
 * [0 <- (offset) -> icon_h <- (offset) -> icon_h ..... -> y]
 */
#define	GET_OFFSET_Y(y, h, n)				( ( (y) - ( (h) * (n) ) ) / ( (n) + 1 ) )

/* 在[s, s + y]区间 : 按 offset 偏移对齐高为 h 的 ICON 
 * => 得出对齐第 i 个 ICON 的绝对位置 - y轴
 */
#define	GET_Y(i, s, h, offset)				( ( ( (h) * (i) ) + ( (offset) * ( (i) + 1 ) ) ) + (s) )


//简便写法-播放固定视频源的不同区域
#define PLAY_MV(x, y)															\
		do {																	\
			char file_path[FF_MAX_LFN];											\
			strcpy(file_path, VolumeStr[SPI]);									\
			strcat(file_path, File_Table.file[FLASH_VIDEO_AREA_INDEX].name);	\
			mv_task_init(file_path);											\
            lcd_set_post(LAYER_2_VIDEO, x, y, 0, 0);							\
			lcd_set_alpha(LAYER_2_VIDEO, 0xFF);									\
			lcd_set_color_key(LAYER_2_VIDEO, false, 0, 0, 0);					\
		} while(0)
									
//--------------------------------------全局宏------------------------------------//
// 布局采用 从左到右 && 由上至下
// 控件布局对应的索引
#if 1
enum {
	SWM_160 = 2,
	SWM_181,
	SWM_190,
	SWM_201,
	SWM_220,
	SWM_260,
};

enum {
	SWM_320 = 2,
	SWM_341, 
};

#else

#define SWM_160           2
#define SWM_181           3
#define SWM_190           4
#define SWM_201           5
#define SWM_220           6
#define SWM_260           7

#define SWM_320           2
#define SWM_341           3

#endif

// GIF 任务执行周期->图片刷新频率 MS
#define M0_M4_TASK_MS     2000
#define PD_TASK_MS        1000
#define PP_TASK_MS        150

//--------------------------------------类型声明------------------------------------//
//每个页面的切换函数原型必须与该声明一致, 用于跳转/创建页面
typedef lv_obj_t *(*custom_cb)(lv_obj_t *parent, void *user_data);

// 页面内控件信息
typedef struct
{
    lv_obj_t *obj;          //节点
    lv_img_dsc_t *img;      //图片源
    lv_coord_t post_x;      //控件位置 - width
    lv_coord_t post_y;      //控件位置 - height
//	uint16_t size_x;     	//控件大小 - width
//  uint16_t size_y;     	//控件大小 - height
    lv_event_cb_t event_cb; //事件回调
    custom_cb user_cb;    	//自定义用户回调
} user_widget_t;

//页面索引枚举
typedef enum
{
    HOME = 0,
    M0,
    M4,
    PD,
    PP,
    GIF_M0,
    GIF_M4,

    PAGE_SIZE //__END__
} page_index_t;

// 页面描述信息
typedef struct
{
    page_index_t index;     //页面索引序号
    lv_obj_t *obj;          //页面父节点
    user_widget_t *widget;  //页面表
    uint16_t widget_size;   //页面表大小
    lv_event_cb_t event_cb; //页面事件回调
} user_page_t;

// GIF 任务实现
typedef struct
{
    lv_obj_t *obj;      // GIF 图片控件
	lv_task_t *task;    // GIF 任务
	lv_img_dsc_t *img;  // GIF 图片源组
	uint16_t index;     // GIF 图片组索引
	uint16_t index_max; // GIF 图片组索引上限
} user_gif_t;

//--------------------------------------变量声明------------------------------------//
//页面表
extern user_page_t Page_Table[];
//页面光标对象
extern lv_obj_t *Page_Obj_Cur;
//页面光标索引
extern uint16_t Page_Obj_Index;
//全局主对象 - TabView
extern lv_obj_t *TabView;
//全局 GIF 实现
extern user_gif_t GIF;
//视频跟随触摸标志(video with touch)
extern volatile bool Video_Touch_Flag;

//--------------------------------------函数声明------------------------------------//
/**
 * @brief 	显示开机动画并在后台预加载主页图片素材
 * @param 	\
 * @retval 	0 - success; 非0 - error
 */
uint8_t ui_loading(void);

/**
 * @brief 	创建主桌面
 * @param 	\
 * @retval 	\
 * @note 	调用该函数之前请保证素材已加载至 SDRAM (即 boot_loading() 完成调用)
 */
void create_desktop_main(void);

/**
 * @brief 	创建主桌面
 * @param 	parent 		  - 页面父结点
 * 			widget_table  - 页面表
 *          table_size    - 表大小
 * @retval 	lv_obj_t * 	  - 页面父结点
 */
lv_obj_t *page_create(lv_obj_t *parent, user_widget_t *widget_table, uint32_t table_size);

/**
 * @brief	清理 GIF 组件
 * @param 	GIF
 * @retval	\
 */
void delete_gif(user_gif_t *gif);

/*为跳转pp页提前加载所需素材资源*/
bool load_pp_jump(void);

/*退出pp页释放资源*/
void clean_pp_quit(void);

//--------------------------------------用户自定义回调声明------------------------------------//
/**
 * @brief	一级菜单 Home / Back 键
 * @param 	parent 		- 页面父节点
 *          user_data 	- 用户自定义数据
 * @retval	obj 		- 页面光标
 */
lv_obj_t *page_jump_home(lv_obj_t *parent, void *user_data);

/**
 * @brief	跳转 M0 / M4 页
 * @param 	parent 		- 页面父节点
 *          user_data 	- 用户自定义数据
 * @retval	obj 		- 页面光标
 */
lv_obj_t *page_jump_m0_m4(lv_obj_t *parent, void *user_data);

/**
 * @brief	跳转 Product 页
 * @param 	parent 		- 页面父节点
 *          user_data 	- 用户自定义数据
 * @retval	obj 		- 页面光标
 */
lv_obj_t *page_jump_pd(lv_obj_t *parent, void *user_data);

/**
 * @brief	跳转 Picture 页
 * @param 	parent 		- 页面父节点
 *          user_data 	- 用户自定义数据
 * @retval	obj 		- 页面光标
 */
lv_obj_t *page_jump_pp(lv_obj_t *parent, void *user_data);

/**
 * @brief	跳转 GIF 页 - M0 / M4
 * @param 	parent 		- 页面父节点
 *          user_data 	- 用户自定义数据
 * @retval	obj 		- 页面光标
 */
lv_obj_t *page_jump_gif(lv_obj_t *parent, void *user_data);

/**
* @brief	退出 GIF 页 - M0 / M4
* @param 	parent 		- 页面父节点
            user_data 	- 用户自定义数据
* @retval	obj 		- 页面光标
*/
lv_obj_t *page_quit_gif(lv_obj_t *parent, void *user_data);

/**
 * @brief	开始/暂停 按钮
 * @param 	parent 		- 页面父节点
 *          user_data 	- 用户自定义数据
 * @retval	obj 		- 页面光标
 */
lv_obj_t *page_show_go(lv_obj_t *parent, void *user_data);

/**
 * @brief	上一张 按钮
 * @param 	parent 		- 页面父节点
 *          user_data 	- 用户自定义数据
 * @retval	obj 		- 页面光标
 */
lv_obj_t *page_show_up(lv_obj_t *parent, void *user_data);

/**
 * @brief	下一张 按钮
 * @param 	parent 		- 页面父节点
 *          user_data 	- 用户自定义数据
 * @retval	obj 		- 页面光标
 */
lv_obj_t *page_show_down(lv_obj_t *parent, void *user_data);

#endif //__UI_PAGE_H__
